<?php
/**
+-----------------------------------------------------------------------------------------------
* GouGuOPEN [ 左手研发，右手开源，未来可期！]
+-----------------------------------------------------------------------------------------------
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
+-----------------------------------------------------------------------------------------------
* @Licensed 勾股OA，开源且可免费使用，但并不是自由软件，未经授权许可不能去除勾股OA的相关版权信息
+-----------------------------------------------------------------------------------------------
* @Author 勾股工作室 <hdm58@qq.com>
+-----------------------------------------------------------------------------------------------
*/
namespace app\lawcase\model;

use think\Model;
use think\facade\Db;

class CaseNode extends Model
{
    // 设置当前模型对应的数据表名称
    protected $name = 'case_node';
    
    // 设置数据表前缀
    protected $prefix = 'oa_';
    
    // 设置主键
    protected $pk = 'id';
    
    // 设置自动时间戳
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';

    /**
     * 获取案件节点列表
     * @param array $where 查询条件
     * @param array $param 分页参数
     * @return array
     */
    public function getList($where = [], $param = [])
    {
        $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
        $order = empty($param['order']) ? 'plan_date asc, id desc' : $param['order'];
        try {
            $list = $this->where($where)
                ->where('delete_time', 0)
                ->order($order)
                ->paginate(['list_rows' => $rows, 'query' => $param])
                ->each(function($item) {
                    // 获取案件信息
                    $case = Db::name('lawcase')->where('id', $item->case_id)->find();
                    $item->case_name = $case ? $case['name'] : '';
                    $item->case_no = $case ? $case['case_no'] : '';

                    // 获取节点类型名称
                    $nodeType = Db::name('node_type')->where('id', $item->node_type)->find();
                    $item->node_type_name = $nodeType ? $nodeType['name'] : '';

                    // 格式化状态
                    $item->status_text = $this->getStatusText($item->status);
                    // 格式化日期
                    $item->plan_date_text = date('Y-m-d', strtotime($item->plan_date));
                    $item->complete_date_text = $item->complete_date ? date('Y-m-d', strtotime($item->complete_date)) : '';

                    return $item;
                });
            return $list;
        } catch (\Exception $e) {
            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
        }
    }

    /**
     * 添加案件节点
     * @param array $data 节点数据
     * @return int|string新增ID
     */
    public function add($data)
    {
        try {
            $data['create_time'] = time();
            // 默认状态为未完成
            if (!isset($data['status'])) {
                $data['status'] = 1;
            }
            $id = $this->strict(false)->insertGetId($data);
            add_log('add', $id, $data);
            return $id;
        } catch (\Exception $e) {
            throw new \Exception('添加案件节点失败：' . $e->getMessage());
        }
    }

    /**
     * 编辑案件节点
     * @param array $data 节点数据
     * @return bool
     */
    public function edit($data)
    {
        try {
            $data['update_time'] = time();
            $res = $this->strict(false)->where('id', $data['id'])->update($data);
            add_log('edit', $data['id'], $data);
            return $res !== false;
        } catch (\Exception $e) {
            throw new \Exception('编辑案件节点失败：' . $e->getMessage());
        }
    }

    /**
     * 删除案件节点
     * @param int|array $ids 节点ID或ID数组
     * @return bool
     */
    public function remove($ids)
    {
        try {
            $ids = is_array($ids) ? $ids : [$ids];
            $this->where('id', 'in', $ids)->update(['delete_time' => time()]);
            foreach ($ids as $id) {
                add_log('delete', $id);
            }
            return true;
        } catch (\Exception $e) {
            throw new \Exception('删除案件节点失败：' . $e->getMessage());
        }
    }

    /**
     * 获取案件节点详情
     * @param int $id 节点ID
     * @return array|null
     */
    public function getDetail($id)
    {
        $detail = $this->where(['id' => $id, 'delete_time' => 0])->find();
        if (!$detail) {
            return null;
        }

        $detail = $detail->toArray();

        // 获取案件信息
        $case = Db::name('lawcase')->where('id', $detail['case_id'])->find();
        $detail['case_name'] = $case ? $case['name'] : '';
        $detail['case_no'] = $case ? $case['case_no'] : '';

        // 获取节点类型名称
        $nodeType = Db::name('node_type')->where('id', $detail['node_type'])->find();
        $detail['node_type_name'] = $nodeType ? $nodeType['name'] : '';

        // 格式化状态
        $detail['status_text'] = $this->getStatusText($detail['status']);
        
        // 格式化日期
        $detail['plan_date_text'] = date('Y-m-d', strtotime($detail['plan_date']));
        $detail['complete_date_text'] = $detail['complete_date'] ? date('Y-m-d', strtotime($detail['complete_date'])) : '';

        return $detail;
    }

    /**
     * 批量添加案件节点
     * @param int $caseId 案件ID
     * @param array $nodes 节点数据 [['node_type' => 1, 'plan_date' => '2023-01-01', 'remark' => '...'], ...]
     * @return array添加结果，包含成功数量和失败数量
     */
    public function batchAdd($caseId, $nodes)
    {
        $success = 0;
        $fail = 0;
        $time = time();Db::startTrans();
        try {
            foreach ($nodes as $node) {
                $data = [
                    'case_id' => $caseId,
                    'node_type' => $node['node_type'],
                    'plan_date' => $node['plan_date'],
                    'status' => 1, // 1表示未完成
                    'remark' => isset($node['remark']) ? $node['remark'] : '','create_time' => $time
                ];
                // 如果提供了完成日期，则设置状态为已完成
                if (isset($node['complete_date']) && !empty($node['complete_date'])) {
                    $data['complete_date'] = $node['complete_date'];$data['status'] = 2; // 2表示已完成
                }$id = $this->strict(false)->insertGetId($data);
                if ($id) {
                    $success++;
                add_log('add', $id, $data);
                } else {
                    $fail++;
                }
            }
            Db::commit();
            return ['success' => $success, 'fail' => $fail];
        } catch (\Exception $e) {
            Db::rollback();
            throw new \Exception('批量添加案件节点失败：' . $e->getMessage());
        }
    }

    /**
     * 完成案件节点
     * @param int $id 节点ID
     * @param string $completeDate 完成日期
     * @param string $remark 备注（可选）
     * @return bool
     */
    public function complete($id, $completeDate, $remark = '')
    {
        try {
            $data = [
                'status' => 2, // 2表示已完成
                'complete_date' => $completeDate,
                'update_time' => time()
            ];
            
            if ($remark) {
                $data['remark'] = $remark;
            }
            
            $res = $this->where('id', $id)->update($data);
            add_log('edit', $id, $data);
            return $res !== false;
        } catch (\Exception $e) {
            throw new \Exception('完成案件节点失败：' . $e->getMessage());
        }
    }

    /**
     * 获取案件的所有节点
     * @param int $caseId 案件ID
     * @param int $status 节点状态，0表示所有状态
     * @return array
     */
    public function getCaseNodes($caseId, $status = 0)
    {
        $query = $this->where(['case_id' => $caseId, 'delete_time' => 0]);
        if ($status > 0) {
            $query->where('status', $status);
        }
        
        return $query->order('plan_date asc, id desc')
            ->select()
            ->each(function($item) {
                // 获取节点类型名称
                $nodeType = Db::name('node_type')->where('id', $item->node_type)->find();
                $item->node_type_name = $nodeType ? $nodeType['name'] : '';
                
                // 格式化状态
                $item->status_text = $this->getStatusText($item->status);// 格式化日期
                $item->plan_date_text = date('Y-m-d', strtotime($item->plan_date));
                $item->complete_date_text = $item->complete_date ? date('Y-m-d', strtotime($item->complete_date)) : '';
                
                return $item;
            })
            ->toArray();
    }

    /**
     * 获取即将到期的节点
     * @param int $days 天数，查询未来几天内到期的节点
     * @param int $lawyerId 律师ID，0表示所有律师
     * @return array
     */
    public function getUpcomingNodes($days = 7, $lawyerId = 0)
    {
        $endDate = date('Y-m-d', strtotime("+{$days} days"));
        $today = date('Y-m-d');
        
        $query = $this->alias('cn')
            ->join('lawcase lc', 'cn.case_id = lc.id')
            ->where([
                ['cn.delete_time', '=', 0],
                ['lc.delete_time', '=', 0],
                ['cn.status', '=', 1], // 1表示未完成
                ['cn.plan_date', '>=', $today],
                ['cn.plan_date', '<=', $endDate]
            ]);
            
        if ($lawyerId > 0) {
            $query->join('case_lawyer cl', 'lc.id = cl.case_id')
                ->where([
                    ['cl.lawyer_id', '=', $lawyerId],
                    ['cl.delete_time', '=', 0]
                ]);
        }
        
        return $query->field('cn.*, lc.name as case_name, lc.case_no')
            ->order('cn.plan_date asc, cn.id desc')
            ->select()
            ->each(function($item) {
                // 获取节点类型名称
                $nodeType = Db::name('node_type')->where('id', $item->node_type)->find();
                $item->node_type_name = $nodeType ? $nodeType['name'] : '';// 格式化状态
                $item->status_text = $this->getStatusText($item->status);
                
                // 格式化日期
                $item->plan_date_text = date('Y-m-d', strtotime($item->plan_date));
                // 计算剩余天数
                $today = strtotime(date('Y-m-d'));
                $planDate = strtotime($item->plan_date);
                $item->days_left = ceil(($planDate - $today) / 86400);
                
                return $item;
            })
            ->toArray();
    }

    /**
     * 获取逾期未完成的节点
     * @param int $lawyerId 律师ID，0表示所有律师
     * @return array
     */
    public function getOverdueNodes($lawyerId = 0)
    {
        $today = date('Y-m-d');
        
        $query = $this->alias('cn')
            ->join('lawcase lc', 'cn.case_id = lc.id')
            ->where([
                ['cn.delete_time', '=', 0],
                ['lc.delete_time', '=', 0],
                ['cn.status', '=', 1], // 1表示未完成
                ['cn.plan_date', '<', $today]
            ]);if ($lawyerId > 0) {
            $query->join('case_lawyer cl', 'lc.id = cl.case_id')
                ->where([
                    ['cl.lawyer_id', '=', $lawyerId],
                    ['cl.delete_time', '=', 0]
                ]);
        }
        
        return $query->field('cn.*, lc.name as case_name, lc.case_no')
            ->order('cn.plan_date asc, cn.id desc')
            ->select()
            ->each(function($item) {
                // 获取节点类型名称
                $nodeType = Db::name('node_type')->where('id', $item->node_type)->find();
                $item->node_type_name = $nodeType ? $nodeType['name'] : '';
                
                // 格式化状态
                $item->status_text = $this->getStatusText($item->status);
                
                // 格式化日期
                $item->plan_date_text = date('Y-m-d', strtotime($item->plan_date));
                
                // 计算逾期天数
                $today = strtotime(date('Y-m-d'));
                $planDate = strtotime($item->plan_date);
                $item->overdue_days = ceil(($today - $planDate) / 86400);
                
                return $item;
            })
            ->toArray();
    }

    /**
     * 获取状态文本
     * @param int $status 状态值
     * @return string
     */
    protected function getStatusText($status)
    {
        $statusMap = [
            1 => '未完成',
            2 => '已完成'
        ];
        
        return isset($statusMap[$status]) ? $statusMap[$status] : '未知状态';
    }

    /**
     * 统计案件节点完成情况
     * @param int $caseId 案件ID
     * @return array包含总数、已完成数、未完成数
     */
    public function getNodeStats($caseId)
    {
        $total = $this->where(['case_id' => $caseId, 'delete_time' => 0])->count();
        $completed = $this->where(['case_id' => $caseId, 'status' => 2, 'delete_time' => 0])->count();
        $pending = $this->where(['case_id' => $caseId, 'status' => 1, 'delete_time' => 0])->count();
        
        return [
            'total' => $total,
            'completed' => $completed,
            'pending' => $pending,'completion_rate' => $total > 0 ? round(($completed / $total) * 100, 2) : 0
        ];
    }

    /**
     * 获取律师的节点统计
     * @param int $lawyerId 律师ID
     * @return array 包含总数、已完成数、未完成数、逾期数
     */
    public function getLawyerNodeStats($lawyerId)
    {
        $today = date('Y-m-d');
        
        // 获取律师负责的案件ID
        $caseIds = Db::name('case_lawyer')
            ->where(['lawyer_id' => $lawyerId, 'delete_time' => 0])
            ->column('case_id');
            
        if (empty($caseIds)) {
            return [
                'total' => 0,
                'completed' => 0,
                'pending' => 0,
                'overdue' => 0
            ];
        }
        
        $total = $this->where('case_id', 'in', $caseIds)
            ->where('delete_time', 0)
            ->count();
            
        $completed = $this->where('case_id', 'in', $caseIds)
            ->where(['status' => 2, 'delete_time' => 0])
            ->count();
            
        $pending = $this->where('case_id', 'in', $caseIds)
            ->where(['status' => 1, 'delete_time' => 0])
            ->count();$overdue = $this->where('case_id', 'in', $caseIds)
            ->where([
                ['status', '=', 1],
                ['plan_date', '<', $today],
                ['delete_time', '=', 0]
            ])
            ->count();
            
        return [
            'total' => $total,
            'completed' => $completed,
            'pending' => $pending,
            'overdue' => $overdue
        ];
    }
}